

from abc import ABCMeta, abstractmethod
# 利用ABCMeta和abstractmethod来定义抽象类和抽象方法

class Observable:
    """被观察者基类"""

    def __init__(self):
        self.__observers = []

    def addObserver(self, observer):
        self.__observers.append(observer)

    def removeObserver(self, observer):
        self.__observers.remove(observer)

    def notifyObservers(self, object = 0):
        """通知观察者
        object 附带的信息
        """
        for o in self.__observers:
            # 我可以传递全部也可以传递少量,这里传递了全部,还有一些附带信息
            # 可以实现推拉模型
            o.update(self, object)


class Observer(metaclass=ABCMeta):
    """观察者模式基类"""

    @abstractmethod
    def update(self, observable, object):
        pass


class WaterHeater(Observable):
    """热水器"""
    def __init__(self):
        super().__init__()
        self.__temperature = 25

    def getTemperature(self):
        return self.__temperature

    def setTemperature(self, temperature):
        """
            用来监控 __temperature, 只要发生变化就提示
        """
        self.__temperature = temperature
        print("当前温度是：" + str(self.__temperature) + "℃")
        self.notifyObservers()


class WashingMode(Observer):
    """该模式用于洗澡"""
    def update(self, waterHeater: WaterHeater, object):
        if waterHeater.getTemperature() >= 50 and waterHeater.getTemperature() < 70:
            print("温度刚刚好，可以用来洗澡")


class DrinkingMode(Observer):
    """该模式用于饮用"""

    def update(self, waterHeater: WaterHeater, object):
        if waterHeater.getTemperature() >= 100:
            print("水已经烧开了，可以用来洗澡! ")


def testWaterHeater():
    heater = WaterHeater()
    washingObser = WashingMode()
    drinkingObser = DrinkingMode()
    heater.addObserver(washingObser)
    heater.addObserver(drinkingObser)
    heater.setTemperature(40)
    heater.setTemperature(60)
    heater.setTemperature(100)
    

def main():
    testWaterHeater()
    pass


if __name__ == "__main__":
    main()